perm filename INITER.SAI[AP,SYS] blob
sn#069684 filedate 1973-03-12 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00006 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00002 00002 BEGIN "INITER"
00004 00003 SIMPLE PROCEDURE ERROR(VALUE STRING XMESSAGE)
00006 00004 FIELD gets the next field of a line, terminating on a space,tab, or line
00009 00005 Put multiple word keys into the dictionary
00014 00006 MOVE MULTIPLE WORDS UP AND WRITE OUT AND CLOSE FILES
00017 ENDMK
⊗;
BEGIN "INITER"
DEFINE CR="'15",
LF="'12",
CRLF="(CR&LF)",
TAB="'11",
FF="'14",
SPACE="'40",
LINE="1",
FIELD="2",
MULTMAX="10",
MINUS1="2↑18 - 1",
LLEN="'10000",
MAXNBR="500",
XSIZE="3",
SPECS="4",
XLEN="MAXNBR*XSIZE+SPECS",
MAXDLEN="'10000",
WLEN="'6400";
INTEGER ARRAY INDEX[0:XLEN-1];
INTEGER ARRAY DICT[0:MAXDLEN-1];
INTEGER ARRAY WORDS[0:WLEN-1];
INTEGER ARRAY LINKS[0:LLEN-1];
INTEGER FLAG, EOF,BRCHAR,LST,LWD,LEN,I;
STRING KEY,KEY0,KEY1;
LABEL CONT,MULTKEY,TEST;
STRING ARRAY MKEY[2:MULTMAX];
INTEGER BPTR,BWD,MI,LINK;
EXTERNAL INTEGER RPGSW;
DEFINE TESTOVERLAP = "IF BWD ≤ LWD + 3 THEN ERROR(""MAXDLEN TOO SMALL"")";
SIMPLE PROCEDURE ERROR(VALUE STRING XMESSAGE);
BEGIN
OUTSTR("ERROR: "&XMESSAGE&CRLF);
CALL(0,"EXIT");
END;
BOOLEAN SIMPLE PROCEDURE AFTER(VALUE STRING A,B);
BEGIN
A←A&"@";
B←B&"@";
WHILE CVASC(A)=CVASC(B) DO
BEGIN
IF EQU(A,NULL) THEN RETURN(FALSE);
A←A[6 TO ∞];
B←B[6 TO ∞];
END;
RETURN (CVASC(A)>CVASC(B));
END;
SIMPLE PROCEDURE PUTWORD(STRING KEY1);
BEGIN
LEN←LENGTH(KEY1) MIN 19;COMMENT:get the length of KEY1;
KEY1←KEY1&"@@@@@";
FOR I←0 STEP 5 UNTIL LEN DO
BEGIN
WORDS[LST]←CVASC(KEY1); COMMENT: store 5 characters in WORDS;
LST←LST+1; COMMENT: increment the pointer;
KEY1←KEY1[6 TO ∞]; COMMENT: get the rest of KEY1;
END;
END;
SIMPLE PROCEDURE UNDO;
BEGIN
RELEASE(4);
OPEN(5,"DSK",'17,0,0,0,0,0);
ENTER(5,"INDEX",FLAG);
WHILE FLAG DO
BEGIN
RELEASE(5);
CALL(1,"SLEEP");
OPEN(5,"DSK",'17,0,0,0,0,0);
ENTER(5,"INDEX",FLAG);
END;
OPEN(4,"DSK",'17,0,0,0,0,0);
LOOKUP(4,"INDEX",FLAG);
IF FLAG THEN ERROR("SECOND LOOKUP FAILED ON INDEX FILE");
ARRYIN(4,INDEX[0],XLEN);
RELEASE(4);
INDEX[0]←INDEX[2];
FOR I←SPECS STEP 3 UNTIL XLEN-1 DO INDEX[I]←0;
ARRYOUT(5,INDEX[0],XLEN);
END;
COMMENT: FIELD gets the next field of a line, terminating on a space,tab, or line
feed. LINE inputs an entire line, terminating on a line feed only;
SETBREAK(FIELD,"@"&LF,CR&FF,"INS");
SETBREAK(LINE,LF,NULL,"INS");
OPEN(0,"DSK",'10,0,2,0,0,0);
ENTER(0,"DICT",FLAG); COMMENT:dictionary file;
IF FLAG THEN ERROR("ENTER FAILED! ON 'DICT'");
OPEN(1,"DSK",'10,0,2,0,0,0);
ENTER(1,"WORDS",FLAG); COMMENT: output file of keywords;
IF FLAG THEN ERROR("ENTER FAILED ON 'WORDS'");
OPEN(2,"DSK",0,2,0,300,BRCHAR,EOF);
LOOKUP(2,"WORDS.SRT",FLAG);COMMENT: input file of keywords;
IF FLAG THEN ERROR("LOOKUP FAILED ON 'WORDS.SRT'");
OPEN(3,"DSK",'10,0,2,0,0,0);
ENTER(3,"LINKS",FLAG); COMMENT: LINK file;
IF FLAG THEN ERROR("ENTER FAILED ON 'LINKS'");
IF ¬RPGSW THEN BEGIN
OPEN(4,"DSK",'17,0,0,0,0,0);
LOOKUP(4,"INDEX",FLAG);
IF ¬FLAG THEN UNDO COMMENT: UNDO USES CHANNEL 5 TO WRITE OUT A NEW INDEX FILE;
ELSE RELEASE(4);
END;
FOR I←0 STEP 2 UNTIL LLEN-3 DO LINKS[I]←I+2; COMMENT: this links together all the
space in LINKS.
LST←0; COMMENT:pointer into WORDS;
LWD←2; COMMENT:pointer into DICT;
KEY0←"@"; COMMENT:key for comparison;
BWD←MAXDLEN-3; COMMENT:ptr to bottom of DICT;
DO KEY1←INPUT(2,FIELD) UNTIL ¬EQU(KEY1,NULL) ∨ EOF; COMMENT: get the first KEY;
WHILE ¬EOF DO
BEGIN
COMMENT:first we check to see if the KEYS are in order. KEY0 is the last
key, KEY1 is the present key;
MI←1;
IF ¬AFTER(KEY1,KEY0) THEN IF EQU(KEY1,KEY0) THEN
BEGIN
LWD←LWD-2;
GO TO MULTKEY;
END
ELSE ERROR("WORDS OUT OF ORDER: "&KEY0&","&KEY1);
KEY0←KEY1;COMMENT: reset KEY0 for next time;
FOR I←2 STEP 1 UNTIL MULTMAX DO MKEY[I]←NULL;
DICT[LWD]←LST*2↑18; COMMENT: put pointer to WORDS in left half of DICT[LWD];
PUTWORD(KEY1);
IF BRCHAR="@" THEN DICT[LWD+1]←MINUS1;
COMMENT: Put multiple word keys into the dictionary;
MULTKEY:BPTR←DICT[LWD+1] DIV 2↑18;
IF BPTR=0 THEN BPTR←LWD;
WHILE BRCHAR="@" DO
BEGIN
MI←MI+1;
KEY←INPUT(2,FIELD);
LINK←DICT[BPTR+2] LAND '777777;
WHILE LINK≠0 DO
BEGIN
BPTR←LINK;
LINK←DICT[BPTR+2] LAND '777777;
END;
IF EQU(KEY,MKEY[MI]) THEN
IF (LINK←DICT[BPTR+1] DIV 2↑18)≠0 THEN BPTR←LINK ELSE
ELSE BEGIN
IF EQU(MKEY[MI],NULL) THEN DICT[BPTR+1]←BWD*2↑18+DICT[BPTR+1]
ELSE DICT[BPTR+2]←BWD+DICT[BPTR+2];
MKEY[MI]←KEY;
DICT[BWD]←LST*2↑18;
DICT[BWD+2]←BPTR*2↑18;
PUTWORD(KEY);
BPTR←BWD;
BWD←BWD-3;
TESTOVERLAP;
WHILE BRCHAR="@" DO
BEGIN
MI←MI+1;
MKEY[MI]←KEY←INPUT(2,FIELD);
DICT[BWD]←LST*2↑18;
DICT[BWD+2]←BPTR*2↑18;
DICT[BPTR+1]←BWD*2↑18 + MINUS1;
PUTWORD(KEY);
BPTR←BWD;
BWD←BWD-3;
TESTOVERLAP;
END;
END;
END;
FOR I←MI+1 STEP 1 UNTIL MULTMAX DO MKEY[I]←NULL;
LWD←LWD+2; COMMENT:DICT entries are 2 words long;
TESTOVERLAP;
IF BRCHAR≠LF THEN INPUT(2,LINE); COMMENT: this gets rid of everything up to
the next desirable FIELD;
DO KEY1←INPUT(2,FIELD) UNTIL ¬EQU(KEY1,NULL) ∨ EOF; COMMENT: get the next KEY1;
END;
RELEASE(2);
DICT[LWD]←LST*2↑18;
WORDS[LST]←CVASC("?"); COMMENT: make last word in DICT beyond all possible words;
LST←LST+1;
COMMENT MOVE MULTIPLE WORDS UP AND WRITE OUT AND CLOSE FILES;
IF LWD LAND '777777777600 ≠ 0 THEN
LWD←(LWD LAND '777777777600) + 128;
TESTOVERLAP;
BWD←BWD+3;
WHILE BWD<MAXDLEN DO
BEGIN
TEST: IF LWD MOD 128 ≥ 126 THEN LWD ← LWD + 2;
LINK←DICT[BWD+2] DIV 2↑18;
IF DICT[LINK+1] DIV 2↑18=BWD
THEN DICT[LINK+1]←LWD*2↑18 + (DICT[LINK+1] LAND '777777)
ELSE DICT[LINK+2]←LWD + (DICT[LINK+2] LAND '777777000000);
LINK←DICT[BWD+1] DIV 2↑18;
IF LINK≠0 THEN DICT[LINK+2]←LWD*2↑18 + (DICT[LINK+2] LAND '777777);
LINK←DICT[BWD+2] LAND '777777;
IF LINK≠0 THEN DICT[LINK+2]←LWD*2↑18 + (DICT[LINK+2] LAND '777777);
DICT[LWD]←DICT[BWD];
DICT[LWD+1]←DICT[BWD+1];
DICT[LWD+2]←DICT[BWD+2];
LWD←LWD+3;
BWD←BWD+3;
END;
WHILE LWD LAND '177 ≠ 0 DO
BEGIN
DICT[LWD]←0;
LWD←LWD+1;
END;
ARRYOUT(0,DICT[0],LWD);
ARRYOUT(1,WORDS[0],WLEN);
ARRYOUT(3,LINKS[0],LLEN);
OPEN(6,"DSK",0,0,0,0,0,0);
LOOKUP(6,"OCCUR.DAT",FLAG);
IF ¬FLAG THEN RENAME(6,NULL,0,0);
RELEASE(6);
RELEASE(0);
RELEASE(1);
RELEASE(3);
RELEASE(5);
END "INITER"